import React, { useEffect, useState } from 'react';
import { Tag, Table, DatePicker, Button, message, Form, Select, Modal, Input, Radio, Space, Popconfirm, Row, Tooltip } from 'antd';
import dayjs from 'dayjs';
import { branchMergeStatus, mainBranchMergeStatus, checkStatus, reviewStatus } from '@/utils/data';
import { useHeight } from '@/utils/hooks/pagination';
import { useRouter } from 'next/router';
import { colWidth, getQueryString } from '@/utils/tools';
import { getMergeBranchApi, getListApi, createMergeBranchApi, outMergeBranchApi, updateOnlineRecordApi, createMergeRequestApi, toMergeBranchApi } from '@/request/online';
import { newBranchApi, searchApi, getBranchesApi } from '@/request/gitlab';
import { updateMergeStatusApi } from '@/request/story';
import PageTitle from '@/components/pageTitle';
import localDb from '@/utils/localDB';
import Icon from '@/components/layout/Icon';
import MyModal from '@/components/modal';
import styles from './index.module.css';

const selectBox = {
  isMergeToMain: <Select options={mainBranchMergeStatus}></Select>,
  isMergeToUnion: <Select options={branchMergeStatus}></Select>,
  checkStatus: <Select options={checkStatus}></Select>,
  review_status: <Select options={reviewStatus} />,
};

const MergeStatus = (props) => {
  const { label, value } = props;
  return (
    <div className={styles['merge-status-box']}>
      <div className={`${styles['merge-status']} ${styles[`merge-status-${value as number}`]}`}></div>
      <div className={`${styles[`merge-status-text-${value as number}`]}`}>{label}</div>
    </div>
  );
};

interface EditableCellProps extends React.HTMLAttributes<HTMLElement> {
  editing: boolean;
  dataIndex: string;
  title: any;
  type: string;
  record: any;
  index: number;
  children: React.ReactNode;
}

interface TableRow {
  branch: string;
  project_name: string;
  review_status: number;
  developer: string;
  name: string;
  rowSpan: number;
  unionBranch?: string;
  [propName: string]: any;
}

const EditableCell: React.FC<EditableCellProps> = ({ editing, dataIndex, title, type, record, index, children, ...restProps }) => {
  const Node = selectBox[type];
  if (editing) {
    if ((dataIndex === 'review_status' || dataIndex === 'checkStatus') && record.unionBranch) {
      return <td {...restProps}>{children}</td>;
    }
    if (dataIndex === 'isMergeToMain' && !record.unionBranch) {
      return <td {...restProps}>{children}</td>;
    }
    return (
      <td {...restProps}>
        <Form.Item name={dataIndex} style={{ margin: 0 }}>
          {Node}
        </Form.Item>
      </td>
    );
  }
  return <td {...restProps}>{children}</td>;
};

const groupBy = (list, key) => {
  const g = {};
  const data = {};
  list.forEach((item) => {
    g[item[key]] = g[item[key]] || [];
    g[item[key]].push(item);
    if (!item.unionBranch) {
      data[item.project_name] = item.project_id;
    }
  });
  return [g, data];
};

const createTreeData = (list) => {
  for (let i = 0; i < list.length; i += 1) {
    // 寻找开发分支且已经合并到合并分支的。
    // 如果这个分支不是合并分支，并且挂到了某个合并分支
    if (!list[i].unionBranch && list[i].pid) {
      const parent = list.filter((item) => {
        return item.unionBranch && item.project_name === list[i].project_name && item.unionBranch === list[i].pid;
        // return item.unionBranch && item._id === list[i].pid;
      });
      if (parent.length) {
        const data = parent[0];
        data.children = data.children || [];
        data.children.push(list[i]);
        list.splice(i, 1);
        i -= 1;
      }
    }
  }
  return list;
};

const OnlineStory = () => {
  const router = useRouter();
  const [defaultDate, setDefaultDate] = useState<any>();
  const [dataSource, setdataSource] = useState<any>([]);
  const [form] = Form.useForm();
  const [editingKey, setEditingKey] = useState('');
  const [chooseDialog, setChooseDialog] = useState<boolean>(false);
  const [groups, setGroups] = useState<{ label: string; value: string | number }[]>([]); // 项目列表
  const [dialog, setDialog] = useState<boolean>(false);
  const [mergeBranchs, setMergeBranchs] = useState<any[]>([]);
  const [choseMergeBranch, setChoseMergeBranch] = useState<string>('');
  const [curRow, setCurRow] = useState<any>({});
  const [projectForm] = Form.useForm(); // 创建合并分支弹框
  const [branches, setBranches] = useState<any[]>([]); // 分支列表
  const [projectNames, setProjectNames] = useState<string[]>([]); // 分支列表
  const isEditing = (record) => `${String(record._id)}` === editingKey;

  useEffect(() => {
    const time = getQueryString('time');
    if (time) {
      setDefaultDate(dayjs(Number(time)));
    } else {
      setDefaultDate(dayjs());
    }
  }, []);

  // 编辑按钮
  const handleEdit = (record) => {
    form.setFieldsValue({
      isMergeToMain: record.isMergeToMain || 0,
      isMergeToUnion: record.isMergeToUnion || 1,
      checkStatus: record.checkStatus || 0,
      review_status: record.review_status || 0,
    });
    setEditingKey(`${String(record._id)}`);
  };

  // 取消按钮
  const handleCancel = () => {
    setEditingKey('');
  };

  // 添加到合并分支
  const handleAddToMergeBranch = async (record) => {
    try {
      // 获取当前项目的今天创建的合并分支
      const res: any = await getMergeBranchApi({ project_name: record.project_name, online_time: dayjs(defaultDate).format('YYYY-MM-DD') });
      if (res) {
        setChooseDialog(true);
        setMergeBranchs(res);
      }
    } catch (err: any) {
      console.log(err.message);
    }
  };
  const getProjectNames = (list) => {
    if (!list || list.length <= 0) {
      return;
    }
    const names: string[] = list
      .map((item: any) => {
        if (!item.http_url_to_repo) {
          return undefined;
        }
        const arr = item.http_url_to_repo.split('/');
        const name = arr[arr.length - 1].replace('.git', '');
        return name;
      })
      .filter((x) => x);
    setProjectNames(Array.from(new Set(names)));
  };
  // 获取列表
  const handleGetList = async () => {
    if (!defaultDate) return;
    try {
      const result = await getListApi({ online_time: dayjs(defaultDate).format('YYYY-MM-DD') });
      if (result) {
        const temp: any = [];
        // d: 项目名称和idkey value
        // group: 项目名称，数组对象
        // 按项目分组
        const [group, d] = groupBy(result, 'project_name');
        const data2: any = [];
        let data: any = [];
        Object.keys(group).forEach((item) => {
          data = data.concat([...group[item]]);
          data2.push({
            label: item,
            value: d[item],
          });
        });
        getProjectNames(result);
        // changeData(data, 'unionBranch');
        // 生成树形table数据
        console.log(data, 'data');
        createTreeData(data);
        setGroups(data2);
        setdataSource(data);
      }
    } catch (err: any) {
      console.log(err.message);
    }
  };
  // 从合并分支移出
  const handleRemoveOutMergeBranch = async (record) => {
    try {
      const res = await outMergeBranchApi({
        develop_branch: record.branch,
        project_name: record.project_name,
      });
      if (res) {
        handleGetList();
      }
    } catch (err: any) {
      console.log(err.message);
    }
  };

  // 保存按钮
  const handleSave = async (record) => {
    try {
      const res: any = await updateOnlineRecordApi({
        selectRows: [record],
      });
      if (res) {
        handleGetList();
        setEditingKey('');
      }
    } catch (e) {
      console.log(e);
    }
  };
  // 创建merge request
  const handleCreateMerge = async (record: { project_id: number; project_name: string; unionBranch: string; branch: string; name: string; developer: string }) => {
    // 看一下是不是有合并分支。如果有用合并分支。如果没有用branch
    const userInfo: any = localDb.get('userInfo');
    const userId: string = userInfo?.personId || '';
    const { project_id, project_name, unionBranch, branch, name, developer } = record;
    const source_branch: string = unionBranch ? record.unionBranch : branch;
    const params = {
      project_name,
      source_branch,
      id: project_id,
      title: name ? `开发者:${developer} 需求:${name} batchId:${userId}` : `Merge ${source_branch}-${userId} batchId:${userId}`,
    };
    const result = await createMergeRequestApi(params);
    if (result) {
      handleGetList();
    }
  };

  const operationBtn = (record) => {
    if (record.unionBranch || record.mr || record.isMergeToMain === 1) return null;
    if (record.pid) {
      return (
        <Popconfirm
          title="确认移出分支？需要手动回滚代码"
          onConfirm={() => {
            setCurRow(record);
            handleRemoveOutMergeBranch(record);
          }}
        >
          <div className={styles.link}>移除</div>
        </Popconfirm>
      );
    }
    return (
      <div
        className={styles.link}
        onClick={() => {
          setCurRow(record);
          handleAddToMergeBranch(record);
        }}
      >
        添加到合并分支
      </div>
    );
  };

  const handleMr = (record: any) => {
    console.log(record);
    const url: string = record.http_url_to_repo.split('.git')[0];
    const link = `${url}/-/merge_requests/${String(record.mr)}`;
    window.open(link);
    // https://gitlab.jrdaimao.com/easyhome-frontend/easyhome-web-business/-/merge_requests/151
    // https://gitlab.jrdaimao.com/easyhome-frontend/easyhome-web.git
  };

  const handleValidMergedStatus = async (record) => {
    const project: any = await searchApi({ id: record.project_id });
    const res = await updateMergeStatusApi({ _id: record._id, id: record.project_id, source_branch: record.branch, default_branch: project[0].default_branch });
    if (res) {
      message.success('合并状态更新成功');
      handleGetList();
    }
  };

  // 检查状态
  const handleCheckStatus = (record) => {
    const { review_status } = record;
    if (record.checkStatus !== 1) {
      message.warning('验收未通过');
      return false;
    }
    if (review_status !== 2) {
      message.warning('代码检查未通过');
      return false;
    }
    return true;
  };

  // 点击复制
  const handleCopy = () => {
    try {
      const namesStr = projectNames.join('\n');
      if (navigator.clipboard && window.isSecureContext) {
        // navigator clipboard 向剪贴板写文本
        navigator.clipboard.writeText(namesStr);
        message.success('复制成功');
      } else {
        const textArea = document.createElement('textarea');
        textArea.value = namesStr;
        document.body.appendChild(textArea);
        textArea.focus();
        textArea.select();
        document.execCommand('copy');
        message.success('复制成功');
        document.body.removeChild(textArea);
      }
    } catch (err) {
      console.error('复制失败', err);
    }
  };

  // 项目名复制
  const handleProjectNameCopy = (e) => {
    e.preventDefault();
    e.stopPropagation();
    handleCopy();
  };

  const columns = [
    {
      title: '需求名称',
      dataIndex: 'name',
      width: '200px',
      fixed: 'left',
      showSorterTooltip: false,
      sorter: (a, b) => String(a?.name).localeCompare(String(b?.name)),
      render: (text, record: { id: string; source: string }) => {
        return record.source === 'tapd' ? (
          <a href={`https://www.tapd.cn/41194427/prong/stories/view/${record.id}`} target="_blank" className="tableTitle">
            {text}
          </a>
        ) : (
          <Button type="link" style={{ padding: 0 }}>
            {text}
          </Button>
        );
      },
    },
    {
      title: () => (
        <div className={styles.project_name_copy}>
          项目名称
          <Tooltip title="复制项目名称">
            <Icon onClick={handleProjectNameCopy} src="/images/onlineStoryCopy.svg" width={18} height={18} />
          </Tooltip>
        </div>
      ),
      showSorterTooltip: false,
      dataIndex: 'project_name',
      fixed: 'left',
      width: '200px',
      sorter: (a, b) => String(a?.project_name).localeCompare(String(b?.project_name)),
      render: (text: string, record: any) => (
        <a href={record.http_url_to_repo} target="_blank" className="tableTitle">
          {text}
        </a>
      ),
    },
    {
      title: '开发人',
      dataIndex: 'developer',
      width: '120px',
      showSorterTooltip: false,
      sorter: (a, b) => String(a?.developer).localeCompare(String(b?.developer)),
      render: (text: string[]) => <span>{Array.isArray(text) && text.join('、')}</span>,
    },
    {
      title: '开发分支',
      dataIndex: 'branch',
      width: '350px',
      render(text, record) {
        if (record.unionBranch) {
          return (
            <div>
              {text}
              <span className={styles.merge}>合并分支</span>
              {/* <Tag color="#108ee9" bordered={false} style={{ marginLeft: '10px' }}>
                合并分支
              </Tag> */}
            </div>
          );
        }
        return <div>{text}</div>;
      },
    },
    {
      title: '代码检查',
      dataIndex: 'review_status',
      width: '150px',
      editable: true,
      showSorterTooltip: false,
      sorter: (a, b) => String(a?.review_status).localeCompare(String(b?.review_status)),
      render(text: number, record) {
        if (record.unionBranch) return null;
        // const selectBox = {
        //   isMergeToMain: <Select options={mainBranchMergeStatus}></Select>,
        //   isMergeToUnion: <Select options={branchMergeStatus}></Select>,
        //   checkStatus: <Select options={checkStatus}></Select>,
        //   review_status: <Select options={reviewStatus} />,
        // };
        return (
          <Select
            suffixIcon={<Icon src="/images/arrow-down-solid-white.png" width={16} height={16} />}
            className={`code-selector code-select-bg${text} `}
            dropdownStyle={{ width: '100px', minWidth: '100px' }}
            options={reviewStatus}
            style={{ width: '80px' }}
            placeholder="review状态"
            value={text}
            onChange={(e) => {
              handleSave({ ...record, review_status: e, checkStatus: undefined });
            }}
          />
        );
      },
    },
    {
      title: '验收状态',
      dataIndex: 'checkStatus',
      width: '120px',
      editable: true,
      sorter: (a, b) => {
        if (a && b) {
          return a.checkStatus - b.checkStatus;
        }
        return true;
      },
      render(text: number, record) {
        if (record.unionBranch) return null;
        return (
          <Select
            suffixIcon={<Icon src={`/images/arrow-down-${text}.png`} width={16} height={16} />}
            className={`check-selector check-select-bg${text}`}
            dropdownStyle={{ width: '100px', minWidth: '100px' }}
            options={checkStatus}
            style={{ width: '80px' }}
            placeholder="验收状态"
            value={text}
            onChange={(e) => {
              handleSave({ ...record, checkStatus: e, review_status: undefined });
            }}
          ></Select>
        );
      },
    },
    // {
    //   title: '统一合并分支名称',
    //   dataIndex: 'unionBranch',
    //   width: '250px',
    //   render(text, record) {
    //     return <span>{text || ''}</span>;
    //   },
    // },
    {
      title: '创建Mr',
      dataIndex: 'mr',
      align: 'center',
      width: '100px',
      render(text, record) {
        return record.pid ? null : (
          <div
            className={styles.link}
            onClick={() => {
              const status = handleCheckStatus(record);
              if (status) {
                handleCreateMerge(record);
              }
            }}
          >
            创建
          </div>
        );
      },
    },
    {
      title: '合并到主分支',
      dataIndex: 'isMergeToMain',
      width: '120px',
      editable: true,
      align: 'center',
      render(text, record) {
        // if (!record.mr) return null;
        if (record.pid) return null;
        const data = mainBranchMergeStatus.filter((item) => item.value === text)[0];
        if (data?.value === 2) {
          console.log(data);
          return (
            <Button
              type="link"
              onClick={() => {
                handleMr(record);
              }}
            >
              {data.label}
            </Button>
          );
        }
        return <MergeStatus label={data.label} value={data.value} />;
      },
    },
    {
      title: '操作',
      dataIndex: 'operation',
      width: '160px',
      fixed: 'right',
      render: (_: any, record: any) => {
        // if (!record.unionBranch) return null;
        const editable = isEditing(record);
        return editable ? (
          <>
            <div
              className={styles.link}
              onClick={() => {
                handleSave(record);
              }}
            >
              保存
            </div>
            <div
              className={styles.link}
              onClick={() => {
                handleCancel();
              }}
            >
              取消
            </div>
          </>
        ) : (
          <>
            {record.mr || record.isMergeToMain === 1 || record.unionBranch ? null : (
              <>
                {/* <Button
                  type="link"
                  onClick={() => {
                    handleEdit(record);
                  }}
                >
                  编辑
                </Button> */}
                <div
                  className={styles.link}
                  onClick={() => {
                    router.push(`/storyManage/edit/${record.id as string}`);
                  }}
                >
                  详情
                </div>
              </>
            )}
            {!record.unionBranch && (
              <div
                className={styles.link}
                onClick={() => {
                  handleValidMergedStatus(record);
                }}
              >
                验证合到主分支
              </div>
            )}
            {operationBtn(record)}
          </>
        );
      },
    },
  ];

  // 切换日期
  const handleChange = (date) => {
    setDefaultDate(date);
  };
  // 创建统一合并分支
  const handleCreateUnionBranch = async () => {
    const data = projectForm.getFieldsValue();
    const project_name = groups.filter((item: any) => item.value === data.project)[0].label;
    const res: any = await createMergeBranchApi({
      selectRows: { ...data, project_name },
      onlineTime: dayjs(defaultDate).format('YYYY-MM-DD'),
    });
    if (res) {
      // router.reload();
      handleGetList();
      setDialog(false);
      projectForm.setFieldsValue({});
    }
  };
  // 列
  const mergedColumns: any = columns.map((col) => {
    if (!col.editable) return col;
    return {
      ...col,
      onCell: (record: any) => ({
        record,
        type: col.dataIndex,
        dataIndex: col.dataIndex,
        title: col.title,
        editing: isEditing(record),
      }),
    };
  });
  // 选择要创建合并分支的项目
  // const onChange = (checkedValues) => {
  //   setSelProjects(checkedValues);
  // };
  // 选择合并分支，提交
  const handleChooseBranch = async () => {
    // 发请求。把开发分支合并到合并分支
    const res = await toMergeBranchApi({
      develop_branch: curRow.branch,
      project_name: curRow.project_name,
      merge_branch: choseMergeBranch,
    });
    if (res) {
      setChooseDialog(false);
      setChoseMergeBranch('');
      handleGetList();
    }
  };
  // 递归获取数据
  const whileGet = async (id) => {
    let result = [];
    async function anonymous(per_page, page) {
      const res: any = await getBranchesApi({ id, per_page, page });
      if (res && res.length === 100) {
        result = result.concat(res);
        let p = page;
        await anonymous(100, (p += 1));
      } else {
        result = result.concat(res);
      }
    }
    await anonymous(100, 1);
    return result;
  };
  // 获取某个项目的所有分支
  const getBranchesList = async (id) => {
    try {
      const r = await whileGet(id);
      setBranches(r);
    } catch (err: any) {
      console.log(err);
    }
  };
  // 项目下拉框改变
  const handleProjectChange = (value) => {
    if (value) {
      getBranchesList(value);
      projectForm.setFieldsValue({
        branch: undefined,
        env: undefined,
      });
      const data: any = groups.filter((item: any) => item.value === value)[0];
      return data;
    }
    setBranches([]);
    return {};
  };
  // 分支下拉框改变
  const handleBranchChange = (value) => {
    if (value) {
      const data = branches.filter((item: any) => item.name === value);
      return data[0];
    }
    return {};
  };
  // 查找主分支
  const getMainBranch = async (project: string | number) => {
    const data: any = await searchApi({ id: project });
    if (data) {
      const p: any = data.filter((item: any) => item.id === project)[0];
      return p ? p.default_branch : 'master';
    }
    return '';
  };
  // 创建新分支
  const handleNewBranch = () => {
    const project = projectForm.getFieldValue('project');
    if (!project) {
      message.error('请先选择项目');
    }
    let value = '';
    const onChange = (e) => {
      value = e.target.value;
    };
    const onOk = async () => {
      const mainBranch = await getMainBranch(project);
      const params = {
        id: project,
        ref: mainBranch,
        branch: value,
      };
      try {
        const res: any = await newBranchApi(params);
        if (res) {
          message.success('创建分支成功');
          setBranches([...branches, res]);
        }
      } catch (err: any) {
        console.log(err.message);
      }
    };
    Modal.confirm({
      content: <Input placeholder="请输入新的分支名称" onChange={onChange} />,
      onOk,
    });
  };

  const search = (input, option) => `${String(option.name)}`.toLowerCase().indexOf(input.toLowerCase()) >= 0;

  useEffect(() => {
    handleGetList();
  }, [defaultDate]);

  return (
    <div className="online-story">
      <PageTitle title="上线项目统计" />
      <div>
        <Row justify="space-between" style={{ marginBottom: '20px' }}>
          <div className={`${styles.data} flex`}>
            <div onClick={() => setDefaultDate(defaultDate.add(-1, 'day'))}>
              <Icon src="/images/arrow-left.png" width={24} height={24} style={{ marginTop: '2px', cursor: 'pointer' }} />
            </div>
            <DatePicker bordered={false} onChange={handleChange} value={defaultDate} suffixIcon={null} allowClear={false} className="my-date-picker" popupStyle={{ left: '260px' }} />
            <div onClick={() => setDefaultDate(defaultDate.add(1, 'day'))}>
              <Icon src="/images/arrow-right.png" width={24} height={24} style={{ marginTop: '2px', cursor: 'pointer' }} />
            </div>
          </div>
          <div>
            <Button
              onClick={() => {
                // handleCreateUnionBranch();
                // if (dataSource.length < 1) return;
                handleCopy();
              }}
              style={{ marginLeft: '20px' }}
            >
              复制项目名称
            </Button>
            <Button
              type="primary"
              onClick={() => {
                // handleCreateUnionBranch();
                if (dataSource.length < 1) return;
                setDialog(true);
              }}
              style={{ marginLeft: '20px' }}
            >
              创建统一合并分支
            </Button>
          </div>
        </Row>
      </div>
      <Form form={form} component={false}>
        <Table
          components={{
            body: {
              cell: EditableCell,
            },
          }}
          scroll={{ x: colWidth(mergedColumns), y: useHeight(239).height }}
          // rowSelection={{
          //   type: 'checkbox',
          //   ...rowSelection,
          // }}
          columns={mergedColumns}
          dataSource={dataSource}
          rowKey="_id"
          pagination={false}
        ></Table>
      </Form>
      <MyModal
        title="创建合并分支"
        destroyOnClose
        open={dialog}
        width={600}
        onCancel={() => {
          setDialog(false);
          projectForm.resetFields();
        }}
        onOk={() => {
          handleCreateUnionBranch();
        }}
      >
        <Form form={projectForm}>
          <Form.Item label="选择项目" name="project">
            <Select onChange={handleProjectChange} placeholder="请选择项目">
              {groups.map((item: any) => (
                <Select.Option value={item.value} key={item.value}>
                  {item.label}
                </Select.Option>
              ))}
            </Select>
          </Form.Item>
          <Form.Item label="选择分支" name="branch">
            <Select placeholder="请选择分支" options={branches} filterOption={search} showSearch fieldNames={{ label: 'name', value: 'name' }} />
          </Form.Item>
        </Form>
        <div style={{ textAlign: 'right' }}>
          <Button onClick={handleNewBranch}>创建新的分支</Button>
        </div>
      </MyModal>
      <Modal
        title="选择合并分支"
        destroyOnClose
        open={chooseDialog}
        onOk={() => {
          handleChooseBranch();
        }}
        onCancel={() => {
          setChooseDialog(false);
        }}
      >
        <Radio.Group
          onChange={(e) => {
            setChoseMergeBranch(e.target.value);
          }}
        >
          <Space direction="vertical">
            {mergeBranchs.map((item) => (
              <Radio value={item.unionBranch} key={item.unionBranch}>
                {item.unionBranch}
              </Radio>
            ))}
          </Space>
        </Radio.Group>
      </Modal>
    </div>
  );
};

export default OnlineStory;
